上一篇我們拆解了「所有教室狀態」頁面的整體架構與資料流,今天我們要更進一步,深入探討這個頁面的視覺與互動核心。
在總覽畫面上,每一間教室都被封裝成一張專屬的資訊卡片,讓管理者能一眼看清教室內容,並能直接點擊卡片跳轉至該教室的「完整每週課表」。而這背後負責將資料轉化為卡片視圖、並綁定跳頁事件的幕後功臣,正是 AllClassroomsAdapter.kt。今天就讓我們一起來深究這檔案的實作細節。
這頁面上的 Adapter 設計其實和前面「教室細項設定」的 ClassroomAdapter.kt 相似,只是將原本的單一文字列換成了帶有「教室類型」與「是否可飲食」的卡片佈局。
但這正好體現了「純選單」走向「卡片化資訊看板」的轉變:我們不再只傳入純教室名稱,而是將資料升級為具備完整屬性的 ClassroomInfo UI Model。
這讓每一張教室卡片不再只是一個跳頁按鈕,而是具備即時資訊呈現的獨立單元,真正達成了「一眼綜觀所有教室資訊」的設計初衷。

AllClassroomsAdapter.kt 負責什麼和 Hermes Agent 一起重讀 AllClassroomsAdapter.kt 後,它負責是「所有教室狀態總覽頁」的 RecyclerView Adapter。它接收了 List<ClassroomInfo>,把每間教室顯示成一張卡片,卡片上顯示教室名稱、類型、是否可飲食;當管理者點擊某張卡片時,會進入到下一頁,並用 CLASSROOM_NAME 傳出教室名稱。
整個檔案主要的任務可以分為以下三點:
// 1. 專為卡片 UI 設計的輕量資料類
data class ClassroomInfo(
val name: String,
val type: String,
val foodAllowed: Boolean
)
// 2. ViewHolder 欄位映射
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val nameTextView: TextView = itemView.findViewById(R.id.classroom_name_text)
private val typeTextView: TextView = itemView.findViewById(R.id.classroom_type_text)
private val foodAllowedTextView: TextView = itemView.findViewById(R.id.food_allowed_text)
// 英文代碼轉為中文
fun bind(classroom: ClassroomInfo) {
nameTextView.text = classroom.name
typeTextView.text = when (classroom.type) {
"Normal" -> "一般教室"
"Computer" -> "電腦教室"
"Drawing" -> "製圖教室"
"Lab" -> "實驗室"
"MeetingRoom" -> "研討室"
else -> "未知"
}
//是否可飲食用 true → 是、false → 否 顯示
foodAllowedTextView.text = if (classroom.foodAllowed) "是" else "否"
}
ClassroomInfo 將畫面需要的屬性精準收保留至 3 個欄位,切斷 View 與 Database Entity 的直接依賴。bind(),讓 CardView 上的 item_all_classrooms.xml 能一目了然呈現「教室名稱」、「教室類型」與「是否可飲食」。override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val classroom = classrooms[position]
holder.bind(classroom)
// 點擊卡片跳轉至該教室的完整每週課表
holder.itemView.setOnClickListener {
val context = holder.itemView.context
val intent = Intent(context, ClassroomScheduleDetailActivity::class.java).apply {
putExtra("CLASSROOM_NAME", classroom.name)
}
context.startActivity(intent)
}
SF304),透過 Intent Extra 將 CLASSROOM_NAME 帶往 ClassroomScheduleDetailActivity,完成「總覽 ➔ 單一教室完整課表」的跳轉。@SuppressLint("NotifyDataSetChanged")
fun updateData(newClassrooms: List<ClassroomInfo>) {
this.classrooms = newClassrooms
notifyDataSetChanged()
}
AllClassroomsActivity observe 到新的教室資料時,會呼叫 updateData();這裡用 notifyDataSetChanged() 讓整份列表重新刷新。這條流程主要呈現從教室總覽進入完整課表的過程:
AllClassroomsActivity 將教室資料整理成 List<ClassroomInfo>。AllClassroomsAdapter 接收資料,並透過 RecyclerView 將每間教室顯示成卡片。CLASSROOM_NAME。Intent 將教室名稱傳遞至 AllClassroomsSchedule.kt,再顯示該教室的完整課表。AllClassroomsActivity
「所有教室狀態總覽」
│
▼
List<ClassroomInfo>
「整理教室總覽資料」
│
▼
AllClassroomsAdapter
「接收並顯示教室資料」
│
▼
RecyclerView
「每間教室顯示成一張卡片」
│
▼
使用者點擊教室卡片
│
▼
取得 CLASSROOM_NAME
「取得所選教室名稱」
│
▼
Intent
「傳遞教室名稱」
│
▼
AllClassroomsSchedule.kt
「顯示該教室的完整課表」
AllClassroomsAdapter 是所有教室狀態總覽頁的 RecyclerView Adapter。
AllClassroomsActivity 傳來的 List<ClassroomInfo>,每一筆資料會顯示成一張 item_all_classrooms.xml 卡片。卡片上會顯示教室名稱、教室類型與是否可飲食。ViewHolder.bind() 會把 classroom.name 填到名稱欄,把 classroom.type 從英文代碼轉成中文顯示,並根據 classroom.foodAllowed 顯示「是」或「否」。ClassroomScheduleDetailActivity 的 Intent,並用 CLASSROOM_NAME 傳出教室名稱,讓下一頁知道要顯示哪一間教室的完整課表。ClassroomInfo 是 Activity 與 Adapter 之間傳遞資料的通用模型,卻被宣告在 Adapter 檔案內。建議獨立拆分成專屬的 Model 檔案(如 ClassroomInfo.kt),讓資料結構更乾淨且方便全域複用。when 判斷在多個頁面重複出現。如果日後要新增一種教室類型,就必須逐一翻找修改;應統一收斂為 RoomType 列舉(Enum)集中管理。notifyDataSetChanged(),會強制整個列表打掉重繪,既耗費效能又失去換頁動畫。未來資料量擴大時,應升級為官方推薦的 ListAdapter 搭配 DiffUtil,達成精準的局部刷新。AllClassroomsAdapter 讓「所有教室狀態」頁真正變成一個可讀的總覽。不同於前面的 ClassroomAdapter 只顯示教室名稱,這裡每張卡片會顯示教室名稱、教室類型與是否可飲食,讓管理者不用點進去就能先看到基本資訊。
這個 Adapter 也負責點擊跳頁。當管理者點擊某一間教室時,它會把 CLASSROOM_NAME 傳給 ClassroomScheduleDetailActivity,下一頁再根據這個名稱查出完整課表。這讓整條瀏覽流程串起來:總覽所有教室 → 點選一間 → 查看完整課表。
閱讀這個檔案時,也能看到幾個可維護性問題:Adapter 直接處理頁面跳轉、ClassroomInfo 放在 Adapter 檔案裡、教室類型中英文轉換邏輯與其他頁重複,以及 notifyDataSetChanged() 的整體刷新比較粗略。這些都不是立即錯誤,但很適合放進後續改善清單。
一句話重點總結此 Adapter:
AllClassroomsAdapter把ClassroomInfo顯示成教室狀態卡片,並在點擊卡片時把CLASSROOM_NAME傳給ClassroomScheduleDetailActivity。
拆解完所有教室狀態頁的列表 Adapter 之後,點擊某個教室卡片後,下一個無庸置疑我們要進入到「單一教是完整課表頁」來查看一週的有課時段。
明明這是一支「找空教室」的 App,為什麼點進完整課表後,畫面上標示的反而是「有課時段」? 這和邏輯以及管理者閱讀每週課表矩陣時的視覺直覺有著很大的關係。
下一篇,我們將深入剖析完整課表頁- AllClassroomsSchedule.kt ,理解單一教室完整課表頁如何接收 CLASSROOM_NAME,並將代表有課時段的 "X" 呈現在一週課表畫面上。